#include "stdafx.h"
#include "Texture.h"

#include "GlobalAppData.h"

using namespace mgfx;
using namespace mcore;

Texture::ResourceMap Texture::mResources = Texture::ResourceMap();

Texture * Texture::createFromFile(const std::string & fileName)
{
	ResourceMap::const_iterator found = mResources.find(fileName);
	if(found != mResources.end())
	{
		return found->second;
	}
	else
	{
		ID3D11ShaderResourceView * rv = 0;
		HR(D3DX11CreateShaderResourceViewFromFile(GlobalAppData::Instance.Device, fileName.c_str(), 0, 0, &rv, 0));

		Texture * tex = new Texture;
		tex->mResourceView = rv;
		mResources[fileName] = tex;

		return tex;
	}
}

Texture * Texture::createEmpty(const std::string & name, int width, int height)
{
	ResourceMap::const_iterator found = mResources.find(name);
	if(found != mResources.end())
	{
		return found->second;
	}
	else
	{
		byte * data = new byte[width * height];

		D3D11_SUBRESOURCE_DATA initData;
		initData.pSysMem = data;
		initData.SysMemPitch = width * sizeof(byte);

		D3D11_TEXTURE2D_DESC texDesc;
		texDesc.MiscFlags = 0;
		texDesc.Width = width;
		texDesc.Height = height;
		texDesc.MipLevels = texDesc.ArraySize = 1;
		texDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
		texDesc.SampleDesc.Count = 1;
		texDesc.SampleDesc.Quality = 0;
		texDesc.Usage = D3D11_USAGE_DYNAMIC;
		texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
		texDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;

		ID3D11Texture2D * tex = NULL;
		HR(GlobalAppData::Instance.Device->CreateTexture2D(&texDesc, &initData, &tex));

		D3D11_SHADER_RESOURCE_VIEW_DESC rvDesc;
		rvDesc.Format = texDesc.Format;
		rvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
		rvDesc.Texture2D.MipLevels = 1;
		rvDesc.Texture2D.MostDetailedMip = 0;

		ID3D11ShaderResourceView * rv = 0;
		HR(GlobalAppData::Instance.Device->CreateShaderResourceView(tex, &rvDesc, &rv));

		Texture * texture = new Texture;
		texture->mResourceView = rv;
		texture->mTexture = tex;
		mResources[name] = texture;

		delete [] data;

		return texture;
	}
}

void Texture::freeAll()
{
	ResourceMap::iterator itr, end = mResources.end();
	for(itr = mResources.begin() ; itr != end ; ++itr)
	{
		delete itr->second;
	}
}

void Texture::setData(const byte * data)
{
	D3D11_MAPPED_SUBRESOURCE subresource;
	HR(GlobalAppData::Instance.DeviceContext->Map(mTexture, 0, D3D11_MAP_WRITE_DISCARD, 0, &subresource));

	//for()
	memcpy(subresource.pData, data, subresource.DepthPitch);
	
	GlobalAppData::Instance.DeviceContext->Unmap(mTexture, 0);
}

Texture::Texture()
{
	mTexture = NULL;
}

Texture::~Texture()
{
	ReleaseCOM(mResourceView);
	ReleaseCOM(mTexture);
}